import { getInstructionVersion, getProject, listRuns } from "@autoscholar/core"; import Link from "next/link"; import { notFound } from "next/navigation"; import { CodeBlock } from "@/components/CodeBlock"; import { MarkdownView } from "@/components/MarkdownView"; import { StatusBadge } from "@/components/StatusBadge"; import { disciplineLabel, fmtDateTime, fmtUsd } from "@/lib/format"; import { db } from "@/lib/server/db"; export const dynamic = "force-dynamic"; export default async function ProjectDetail({ params, searchParams, }: { params: Promise<{ id: string }>; searchParams: Promise<{ v?: string }>; }) { const { id } = await params; const { v } = await searchParams; const d = db(); let data: Awaited>; try { data = await getProject(d, id); } catch { notFound(); } const runs = await listRuns(d, { projectId: id, limit: 50 }); const selected = v ? await getInstructionVersion(d, v).catch(() => null) : data.versions[0] ? await getInstructionVersion(d, data.versions[0].id) : null; return (

Projects

{data.project.title}

{disciplineLabel(data.project.discipline)} · {data.project.description || "no description"}

Instruction versions

    {data.versions.length === 0 &&
  • None uploaded.
  • } {data.versions.map((iv) => (
  • v{iv.version} · {iv.filename}

    {iv.sha256.slice(0, 16)} · {iv.byteSize} B · {fmtDateTime(iv.createdAt)}

    {iv.note &&

    {iv.note}

    } Re-run / duplicate
  • ))}

Runs

    {runs.length === 0 &&
  • No runs.
  • } {runs.map((r) => (
  • {r.title} {fmtUsd(r.totalCostUsd)}
  • ))}
{selected ? (

Instruction v{selected.version} (immutable)

{selected.sha256}
{selected.frontmatter && ( )}
Rendered preview (sanitized)
Raw text
) : (

Select a version.

)}
); }